package com.moody.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.moody.hibernate.dao.AssociateAccountDAO;
import com.moody.hibernate.dao.BankCustDepositDAO;
import com.moody.hibernate.dao.BankCustGuaranteeDAO;
import com.moody.hibernate.dao.BankCustLoanDAO;
import com.moody.hibernate.dao.CustAddressDAO;
import com.moody.hibernate.dao.CustEventsDAO;
import com.moody.hibernate.dao.CustInfoDAO;
import com.moody.hibernate.dao.CustManagerDAO;
import com.moody.hibernate.dao.CustOperationDAO;
import com.moody.hibernate.dao.CustStockholderDAO;
import com.moody.hibernate.dao.DebtInfoDAO;
import com.moody.hibernate.dao.ExtratInfoDAO;
import com.moody.hibernate.dao.GroupInfoDAO;
import com.moody.hibernate.dao.IndBankDAO;
import com.moody.hibernate.dao.IndInfoDAO;
import com.moody.hibernate.dao.IndOccardDAO;
import com.moody.hibernate.dao.IndOguaranteeDAO;
import com.moody.hibernate.dao.IndOloanDAO;
import com.moody.hibernate.dao.MemberInfoDAO;
import com.moody.hibernate.dao.PdHDAO;
import com.moody.hibernate.dao.ReportDataDAO;
import com.moody.hibernate.dao.ReportListDAO;
import com.moody.hibernate.dao.ReportModelDAO;
import com.moody.hibernate.dao.SpecialRecordDAO;
import com.moody.hibernate.dao.SpecialTradeDAO;
import com.moody.hibernate.domain.AssociateAccount;
import com.moody.hibernate.domain.BankCustGuarantee;
import com.moody.hibernate.domain.BankCustDeposit;
import com.moody.hibernate.domain.BankCustLoan;
import com.moody.hibernate.domain.CollateralInfo;
import com.moody.hibernate.domain.CustAddress;
import com.moody.hibernate.domain.CustEvents;
import com.moody.hibernate.domain.CustInfo;
import com.moody.hibernate.domain.CustManager;
import com.moody.hibernate.domain.CustOperation;
import com.moody.hibernate.domain.CustStockholder;
import com.moody.hibernate.domain.DebtInfo;
import com.moody.hibernate.domain.ExtratInfo;
import com.moody.hibernate.domain.FinanFinancialIndexSheet;
import com.moody.hibernate.domain.GroupInfo;
import com.moody.hibernate.domain.IndBank;
import com.moody.hibernate.domain.IndInfo;
import com.moody.hibernate.domain.IndOccard;
import com.moody.hibernate.domain.IndOguarantee;
import com.moody.hibernate.domain.IndOloan;
import com.moody.hibernate.domain.MemberInfo;
import com.moody.hibernate.domain.OrgInfo;
import com.moody.hibernate.domain.PdH;
import com.moody.hibernate.domain.ReportData;
import com.moody.hibernate.domain.ReportList;
import com.moody.hibernate.domain.ReportListId;
import com.moody.hibernate.domain.ReportModel;
import com.moody.hibernate.domain.RoleInfo;
import com.moody.hibernate.domain.SpecialRecord;
import com.moody.hibernate.domain.SpecialTrade;
import com.moody.hibernate.domain.UserInfo;
import com.moody.init.DataDictionary;
import com.moody.init.RoleRightInit;
import com.moody.service.CustomerService;
import com.moody.service.SystemService;

/*
 * Copyright © Moody analytics
 *
 * @Author: Wang Fuqiang
 * @Time: 2011-8-30 下午04:44:49
 * @Modified by: Wangfuqiang 2011-09-01
 * @Description: 
 */
@SuppressWarnings("unchecked")
@Service
public class CustomerServiceImpl implements CustomerService {
	WebApplicationContext web=ContextLoader.getCurrentWebApplicationContext();
	ServletContext servletContext=web.getServletContext();
	Map<String, List<String>> orgMap = (Map<String, List<String>>)servletContext.getAttribute("OrgMap");
	
	@Resource
	private SystemService systemService;
	
	@SuppressWarnings("unused")
	private static final Logger log = LoggerFactory
			.getLogger(CustomerServiceImpl.class);
	ApplicationContext ctx = new ClassPathXmlApplicationContext(
			"applicationContext.xml");
	
	private CustAddressDAO custAddressDao = CustAddressDAO
			.getFromApplicationContext(ctx);
	private CustInfoDAO custInfoDao = CustInfoDAO
			.getFromApplicationContext(ctx);
	private CustOperationDAO custOperationDao = CustOperationDAO
			.getFromApplicationContext(ctx);
	private CustManagerDAO custManagerDAO = CustManagerDAO
			.getFromApplicationContext(ctx);
	private CustStockholderDAO custStockholderDAO = CustStockholderDAO
			.getFromApplicationContext(ctx);
	private CustEventsDAO custEventsDAO = CustEventsDAO
			.getFromApplicationContext(ctx);
	private BankCustDepositDAO bankCustDepositDAO = BankCustDepositDAO
			.getFromApplicationContext(ctx);
	private BankCustLoanDAO bankCustLoanDAO = BankCustLoanDAO
			.getFromApplicationContext(ctx);
	private BankCustGuaranteeDAO bankCustGuaranteeDAO = BankCustGuaranteeDAO
			.getFromApplicationContext(ctx);
	private ReportListDAO reportListDAO = ReportListDAO
			.getFromApplicationContext(ctx);
	private ReportDataDAO reportDataDAO = ReportDataDAO
			.getFromApplicationContext(ctx);
	private ReportModelDAO reportModelDAO = ReportModelDAO.getFromApplicationContext(ctx);
	private ExtratInfoDAO extratInfoDAO = ExtratInfoDAO
			.getFromApplicationContext(ctx);
	private IndInfoDAO indInfoDAO = IndInfoDAO.getFromApplicationContext(ctx);
	private IndOccardDAO indOccardDAO = IndOccardDAO
			.getFromApplicationContext(ctx);
	private IndOloanDAO indOloanDAO = IndOloanDAO
			.getFromApplicationContext(ctx);
	private IndOguaranteeDAO indOguaranteeDAO = IndOguaranteeDAO
			.getFromApplicationContext(ctx);
	private IndBankDAO indBankDAO = IndBankDAO.getFromApplicationContext(ctx);
	private SpecialTradeDAO specialTradeDAO = SpecialTradeDAO
			.getFromApplicationContext(ctx);
	private SpecialRecordDAO specialRecordDAO = SpecialRecordDAO
			.getFromApplicationContext(ctx);
	private PdHDAO pdhDAO = PdHDAO.getFromApplicationContext(ctx);
	private GroupInfoDAO groupInfoDAO = GroupInfoDAO.getFromApplicationContext(ctx);
	private MemberInfoDAO memberInfoDAO = MemberInfoDAO.getFromApplicationContext(ctx);
	private DebtInfoDAO debtInfoDAO = DebtInfoDAO.getFromApplicationContext(ctx);
	private AssociateAccountDAO associateAccountDAO = AssociateAccountDAO.getFromApplicationContext(ctx);

	public void insertAddress(CustAddress custAddress) {
		custAddressDao.save(custAddress);
	}

	@SuppressWarnings("unchecked")
	public List<CustAddress> findAllByCustId(String custId) {
		return custAddressDao.findByCustId(custId);
	}

	@SuppressWarnings("unchecked")
	public List<CustInfo> findAllByCustType(String custType,String userId, String orgId) {
		if(custType == null  || userId == null || "".equals(userId) || orgId == null || "".equals(orgId))
			return new ArrayList<CustInfo>();
		List<String> subOrgIdList = orgMap.get(orgId);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");

		List<CustInfo> resultList = custInfoDao.findCustInfo(custType,userId,subOrgIdList);
		//不同权限可见性不同：
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(custInfoDao.findCustInfo(custType,userId,selfList));
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(custInfoDao.findCustInfo(custType,userId,selfList));
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(custInfoDao.findCustInfo(custType,userId,selfList));
		}
		
		for(CustInfo cust : resultList){
			if(systemService.findUserById(cust.getInputUserId())!=null){
				String userName = systemService.findUserById(cust.getInputUserId()).getUsername();
				String orgName = systemService.findOrgById(cust.getInputOrgId()).getOrgname();
				cust.setInputUserName(userName);
				cust.setInputOrgName(orgName);
			}
		}
		
		return resultList;
	} 

	public void insertGeneral(CustInfo custInfo) {
		custInfoDao.save(custInfo);
	}

	public void updateCustInfo(CustInfo custInfo) {
		custInfoDao.update(custInfo);
	}

	public void insertOperation(CustOperation custOpera) {
		custOperationDao.save(custOpera);
	}

	public Boolean isCustExist(String custName, String custNo , String organizationID,
			String busiLicenseID) {
		return custInfoDao.isCustExist(custName, custNo, organizationID, busiLicenseID);

	}

	@SuppressWarnings("unchecked")
	public List<CustInfo> myCutomerList(String custType) {
		return custInfoDao.myCutomerList(custType);
	}

	public void deleteAddressByCustId(String custId) {
		custAddressDao.deleteByCustId(custId);
	}

	public void insertCustManager(CustManager custManager) {
		custManagerDAO.save(custManager);
	}

	@SuppressWarnings("unchecked")
	public List<CustManager> findManagerByCustId(String custId) {
		return custManagerDAO.findByCustId(custId);
	}

	public void insertCustEvents(CustEvents custEvents) {
		custEventsDAO.save(custEvents);
	}

	@SuppressWarnings("unchecked")
	public List<CustEvents> findEventsByCustId(String custId) {
		return custEventsDAO.findByCustId(custId);
	}

	public void insertGuarantee(BankCustGuarantee bankCustGuarantee) {
		bankCustGuaranteeDAO.save(bankCustGuarantee);
	}

	@SuppressWarnings("unchecked")
	public List<BankCustGuarantee> findGuaranteeByCustId(String custId) {
		return bankCustGuaranteeDAO.findByCustId(custId);
	}

	public void insertDeposit(BankCustDeposit bankCustDeposit) {
		bankCustDepositDAO.save(bankCustDeposit);
	}

	@SuppressWarnings("unchecked")
	public List<BankCustDeposit> findDepositByCustId(String custId) {
		return bankCustDepositDAO.findByCustId(custId);
	}

	public void insertLoan(BankCustLoan bankCustLoan) {
		bankCustLoanDAO.save(bankCustLoan);
	}

	@SuppressWarnings("unchecked")
	public List<BankCustLoan> findLoanByCustId(String custId) {
		return bankCustLoanDAO.findByCustId(custId);
	}

	public void insertReport(ReportList reportList) {
		reportListDAO.save(reportList);
	}

	public void insertReportData(ReportData rd) {
		reportDataDAO.save(rd);
	}

	public CustInfo findCustByCustId(String custId) {

		return custInfoDao.findById(custId);
	}
	
	public CustInfo findCustByCustNo(String custNo){
		return (CustInfo) custInfoDao.findByProperty("custNo", custNo).get(0);
	}
	
	public CustInfo findCustAndCreditByCustId(String custId) {

		CustInfo  custInfo = custInfoDao.findById(custId);
		PdH pdh = pdhDAO.findNewestPDByCustId(custId);
		if(pdh == null)return custInfo;
		
		String bdcreditLevel = pdh.getConfirmPdlevel();
		String bdcreditDate = pdh.getConfirmDate();
		
		if(bdcreditLevel == null || bdcreditDate == null){
			bdcreditLevel = "";
			bdcreditDate = "";
		}
		custInfo.setBdcreditLevel(bdcreditLevel);
		custInfo.setBdcreditDate(bdcreditDate);
		
		return custInfo;
		

		
	}
	public void deleteReport(ReportList reportList){
		reportListDAO.delete(reportList);
	}

	public void deleteCustomerById(String custId) {
		custInfoDao.deleteById(custId);
	}

	public void insertReportDataList(List<ReportData> list) {
		reportDataDAO.insertReportDataList(list);
	}

	// 查找该客户财务报表
	public Map findRecentReport(String custId) {
		return reportListDAO.findRecentReport(custId);
	}

	// 查找该客户财务报表数据项
	public List<ReportData> findRecentReportData(ReportList recentReport,
			String reportNo) {
		return reportDataDAO.findRecentReportData(recentReport, reportNo);
	}

	public List<ReportData> findRecentReportData(ReportList recentReport) {

		return reportDataDAO.findRecentReportData(recentReport);
	}

	@SuppressWarnings("unchecked")
	public List<CustInfo> findLimitCustByCustType(String custType, int start,
			int limit) {
		return custInfoDao.findLimitCustByCustType(custType, start, limit);
	}

	public void deleteAddressById(String addSerialNo) {
		custAddressDao.deleteById(addSerialNo);
	}

	public CustAddress findAddressById(String addSerialNo) {
		return custAddressDao.findById(addSerialNo);
	}

	public void deleteManagerById(String addSerialNo) {
		custManagerDAO.delete(custManagerDAO.findById(addSerialNo));
	}

	public void updateAddress(CustAddress custAddress) {
		custAddressDao.update(custAddress);
	}

	public CustManager findManagerById(String addSerialNo) {
		return custManagerDAO.findById(addSerialNo);
	}

	public void deleteEventsById(String addSerialNo) {
		custEventsDAO.deleteById(addSerialNo);
	}

	public void updateManage(CustManager custManager) {
		custManagerDAO.update(custManager);
	}

	public CustEvents findEventsById(String serialNo) {
		// TODO Auto-generated method stub
		return custEventsDAO.findById(serialNo);
	}

	public void updateEvent(CustEvents custEvent) {
		// TODO Auto-generated method stub
		custEventsDAO.update(custEvent);
	}

	public BankCustGuarantee findGuaranteeById(String serialNo) {
		// TODO Auto-generated method stub
		return bankCustGuaranteeDAO.findById(serialNo);
	}

	public void updateGuarantee(BankCustGuarantee bankCustGuarantee) {
		// TODO Auto-generated method stub
		bankCustGuaranteeDAO.update(bankCustGuarantee);
	}

	public void deleteGuaranteeById(String serialNo) {
		// TODO Auto-generated method stub
		bankCustGuaranteeDAO.deleteById(serialNo);
	}

	public BankCustDeposit findDepositById(String addSerialNo) {
		return bankCustDepositDAO.findById(addSerialNo);
	}

	public void deleteDepositById(String addSerialNo) {
		bankCustDepositDAO.delete(bankCustDepositDAO.findById(addSerialNo));
	}

	public void updateDeposit(BankCustDeposit bankCustDeposit) {
		bankCustDepositDAO.update(bankCustDeposit);
	}

	public List<BankCustDeposit> findDepositByCustIdAndType(String custId,
			String type) {
		return bankCustDepositDAO.findDepositByCustIdAndType(custId, type);
	}

	public BankCustLoan findLoanById(String addSerialNo) {
		return bankCustLoanDAO.findById(addSerialNo);
	}

	public void deleteLoanById(String addSerialNo) {
		bankCustLoanDAO.delete(bankCustLoanDAO.findById(addSerialNo));
	}

	public void updateLoan(BankCustLoan bankCustLoan) {
		bankCustLoanDAO.update(bankCustLoan);
	}

	public List<BankCustLoan> findLoanByCustIdAndType(String custId, String type) {
		return bankCustLoanDAO.findLoanByCustIdAndType(custId, type);
	}

	public List<ReportList> findReportListByCustId(String custId) {
		// TODO Auto-generated method stub
		return reportListDAO.findByCustId(custId);
	}

	public ReportList findReportListById(ReportListId reportId) {
		// TODO Auto-generated method stub
		return reportListDAO.findById(reportId);
	}

	public void updateReportList(ReportList reportList) {
		reportListDAO.update(reportList);

	}

	public List<ReportData> findSortedEnterIncome(ReportList report) {
		return reportDataDAO.findSortedEnterIncomeData(report);
	}

	public List<ReportData> findSortedEnterBalance(ReportList report) {
		return reportDataDAO.findSortedEnterBalanceData(report);
	}

	public List<ReportData> findSortedEnterAsset(ReportList report) {
		return reportDataDAO.findSortedEnterAsset(report);
	}

	public List<ReportData> findSortedEnterDebt(ReportList report) {
		return reportDataDAO.findSortedEnterDebt(report);
	}

	public List<ReportData> findSortedSmallBalance(ReportList report) {
		return reportDataDAO.findSortedSmallBalanceData(report);
	}

	public List<ReportData> findSortedSmallAsset(ReportList report) {
		return reportDataDAO.findSortedSmallAsset(report);
	}

	public List<ReportData> findSortedSmallDebt(ReportList report) {
		return reportDataDAO.findSortedSmallDebt(report);
	}

	public List<ReportData> findSortedFinanBalance(ReportList report) {
		return reportDataDAO.findSortedFinanBalanceData(report);
	}

	public List<ReportData> findSortedFinanAsset(ReportList report) {
		return reportDataDAO.findSortedFinanAsset(report);
	}

	public List<ReportData> findSortedFinanDebt(ReportList report) {
		return reportDataDAO.findSortedFinanDebt(report);
	}

	public List<ReportData> findSortedFinanIncome(ReportList report) {
		return reportDataDAO.findSortedFinanIncomeData(report);
	}

	public List<ReportData> findSortedFinanFinancialIndex(ReportList report) {
		return reportDataDAO.findSortedFinanFinancialIndexData(report);
	}

	public List<ReportData> findSortedFinanFinancialIndexInput(ReportList report) {

		List<ReportData> listOfAll = reportDataDAO
				.findSortedFinanFinancialIndexData(report);
		List<ReportData> listOfInput = new ArrayList<ReportData>();

		for (int i = 0; i < listOfAll.size(); i++) {
			ReportData reportDataItem = listOfAll.get(i);
			if (reportDataItem.getDisplayFlag().substring(1).equals("1")) {
				listOfInput.add(reportDataItem);
			}
		}
		return listOfInput;
	}

	@SuppressWarnings("unchecked")
	public List<ExtratInfo> findExtratByCustId(String custId) {
		return extratInfoDAO.findByCustId(custId);
	}

	public void insertExtrat(ExtratInfo extratInfo) {
		extratInfoDAO.save(extratInfo);
	}

	public void deleteExtratById(String addSerialNo) {
		extratInfoDAO.delete(extratInfoDAO.findById(addSerialNo));
	}

	public ExtratInfo findExtratById(String addSerialNo) {
		return extratInfoDAO.findById(addSerialNo);
	}

	public void updateExtrat(ExtratInfo extratInfo) {
		extratInfoDAO.update(extratInfo);
	}

	@SuppressWarnings("unchecked")
	public List<CustInfo> findCustByCondition(String custType, String custName,
			String organizationID, String busiLicenseID) {
		return custInfoDao.findCustByCondition(custType, custName,
				organizationID, busiLicenseID);
	}

	public boolean isReportReady(ReportList report) {
		return reportDataDAO.isReportReady(report);
	}

	public void updateReportStatus(ReportList report, String status) {
		reportListDAO.updateReportStatus(report, status);
	}

//	public List<CustInfo> findAllCustomerByUserId(String userId) {
//		// userId未传值，查找所有用户
//		if (userId == null || userId.equals("")) {
//			return custInfoDao.findAll();
//		} else {
//			return null;
//		}
//	}

	public String getCustNameById(String debtCustId) {
		return custInfoDao.findById(debtCustId).getCustName();
	}

	@SuppressWarnings("unchecked")
	public List<CustInfo> findAllCustomer() {
		return custInfoDao.findAll();
	}

	public List<ReportData> findPreviousYearReportData(ReportList report) {
		ReportList previousReport = reportListDAO
				.findPreviousYearReport(report);
		if (previousReport == null)
			return null;
		else
			return reportDataDAO.findRecentReportData(previousReport);
	}

	public List<ReportData> findSortedEnterCashFlow(ReportList report) {
		return reportDataDAO.findSortedEnterCashFlowData(report);
	}

	public List<ReportData> findSortedSmallCashFlow(ReportList report) {
		return reportDataDAO.findSortedSmallCashFlowData(report);
	}

	public List<CustInfo> findCustomerByIdAndName(String condition,String keyword) {

		return custInfoDao.findByIdAndName(condition, keyword);
	}

	// 查找最新一期年报的财务指标表
	public Map<String, Double> findRecentFIMapByCustId(String custId) {
		Map map = this.findRecentReport(custId);

		int i = 0;
		ReportList lastOneYearReport = null;
		String lastOneDate = "";
		for (Object date : map.keySet()) {
			i++;

			lastOneYearReport = (ReportList) map.get(date);
			lastOneDate = date.toString();
			if (lastOneYearReport != null)
				break;
		}

		List<ReportData> lastOneFIList = this.findRecentReportData(
				lastOneYearReport, "0105");
		// 转化为map形式
		Map dataMap = new HashMap();
		for (ReportData rd : lastOneFIList) {
			if(rd.getItemValue()==null){
				dataMap.put(rd.getReportItemNo(), 0.0);
			}else{
				dataMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}

		return dataMap;

	}

	// 查找最新一期年报的财务报表
	public Map findRecentReportByCustId(String custId) {
		Map map = this.findRecentReport(custId);

		int i = 0;
		ReportList lastOneYearReport = null;
		String lastOneDate = "";
		for (Object date : map.keySet()) {
			if (i > 0) {
				lastOneYearReport = (ReportList) map.get(date);
				lastOneDate = date.toString();
				if (lastOneYearReport != null)
					break;
			}
			i++;
		}
		List<ReportData> lastOneFIList = this
				.findRecentReportData(lastOneYearReport);
		// 转化为map形式
		Map<String, Double> dataMap = new HashMap<String, Double>();
		for (ReportData rd : lastOneFIList) {
			if(rd.getItemValue()==null){
				dataMap.put(rd.getReportItemNo(), 0.0);
			}else{
				dataMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}

		return dataMap;
	}
	
	//查找某月份的年报的财务报表
	public ReportList findReportByTime(String custId, String accountMonth){
		return reportListDAO.findReportByTime(custId, accountMonth);
	}
	
	//查找客户所有的财报月份(年报)
	public List<String> findReportDate(String custId){
		List<String> resultList = new LinkedList<String>();
		List<ReportList> list = reportListDAO.findByCustId(custId);
		for(ReportList report :list){
			//判断是否为年报
			if("01".equals(report.getReportKind()))resultList.add(report.getId().getAccountMonth());
		}
		return resultList;
	}

	public boolean isRetailCustExist(String custName, String custNo,String idtype, String idno) {
		return custInfoDao.isRetailCustExist(custName, custNo,idtype, idno);
	}

	public void insertRetailGeneral(IndInfo custInfo) {
		indInfoDAO.save(custInfo);
	}

	public IndInfo findIndCustByCustId(String custId) {
		return indInfoDAO.findById(custId);
	}

	public void updateIndCustInfo(IndInfo custInfo) {
		indInfoDAO.update(custInfo);
	}

	public IndOccard findIndOccardByCustId(String custId) {
		List<IndOccard> list = indOccardDAO.findByCustId(custId);
		if (list.size() > 0)
			return list.get(0);
		else
			return null;
	}

	public void updateIndOccardInfo(IndOccard custInfo) {
		indOccardDAO.update(custInfo);
	}

	public void insertIndOccard(IndOccard custInfo) {
		indOccardDAO.save(custInfo);
	}

	public IndOloan findIndOloanByCustId(String custId) {
		List<IndOloan> list = indOloanDAO.findByCustId(custId);

		if (list.size() > 0)
			return list.get(0);
		else
			return null;
	}

	public void insertIndOloan(IndOloan custInfo) {
		indOloanDAO.save(custInfo);
	}

	public void updateIndOloanInfo(IndOloan custInfo) {
		indOloanDAO.update(custInfo);
	}

	@SuppressWarnings("unchecked")
	public List<IndOguarantee> findIndOguaranteeByCustId(String custId) {
		return indOguaranteeDAO.findByCustId(custId);
	}

	public void insertIndOguarantee(IndOguarantee indOguarantee) {
		indOguaranteeDAO.save(indOguarantee);
	}

	public void deleteIndOguaranteeById(String addSerialNo) {
		indOguaranteeDAO.delete(indOguaranteeDAO.findById(addSerialNo));
	}

	public void updateIndOguarantee(IndOguarantee indOguarantee) {
		indOguaranteeDAO.update(indOguarantee);
	}

	public IndOguarantee findIndOguaranteeById(String addSerialNo) {
		return indOguaranteeDAO.findById(addSerialNo);
	}

	@SuppressWarnings("unchecked")
	public List<IndBank> findIndBankByCustId(String custId) {
		return indBankDAO.findByCustId(custId);
	}

	public void insertIndBank(IndBank indBank) {
		indBankDAO.save(indBank);
	}

	public void deleteIndBankById(String addSerialNo) {
		indBankDAO.delete(indBankDAO.findById(addSerialNo));
	}

	public void updateIndBank(IndBank indBank) {
		indBankDAO.update(indBank);
	}

	public IndBank findIndBankById(String addSerialNo) {
		return indBankDAO.findById(addSerialNo);
	}

	@SuppressWarnings("unchecked")
	public List<SpecialTrade> findSpecialTradeByCustId(String custId) {
		return specialTradeDAO.findByCustId(custId);
	}

	public void insertSpecialTrade(SpecialTrade specialTrade) {
		specialTradeDAO.save(specialTrade);
	}

	public void deleteSpecialTradeById(String addSerialNo) {
		specialTradeDAO.delete(specialTradeDAO.findById(addSerialNo));
	}

	public void updateSpecialTrade(SpecialTrade specialTrade) {
		specialTradeDAO.update(specialTrade);
	}

	public SpecialTrade findSpecialTradeById(String addSerialNo) {
		return specialTradeDAO.findById(addSerialNo);
	}

	@SuppressWarnings("unchecked")
	public List<SpecialRecord> findSpecialRecordByCustId(String custId) {
		return specialRecordDAO.findByCustId(custId);
	}

	public void insertSpecialRecord(SpecialRecord specialRecord) {
		specialRecordDAO.save(specialRecord);
	}

	public void deleteSpecialRecordById(String addSerialNo) {
		specialRecordDAO.delete(specialRecordDAO.findById(addSerialNo));
	}

	public void updateSpecialRecord(SpecialRecord specialRecord) {
		specialRecordDAO.update(specialRecord);
	}

	public SpecialRecord findSpecialRecordById(String addSerialNo) {
		return specialRecordDAO.findById(addSerialNo);
	}

	public PdH findIndNewestPDByCustId(String custId) {
		return pdhDAO.findNewestPDByCustId(custId);
	}

	public void updateIndPdH(PdH pdh) {
		pdhDAO.update(pdh);
	}

	public void insertIndPdH(PdH pdh) {
		pdhDAO.save(pdh);
	}

	public List<PdH> findIndHistoryPDByCustId(String custId) {
		return pdhDAO.findAllPDByCustId(custId);
	}

	public void deleteIndPDById(String addSerialNo) {
		pdhDAO.delete(pdhDAO.findById(addSerialNo));
	}

	public PdH findIndPDById(String addSerialNo) {
		return pdhDAO.findById(addSerialNo);
	}

	public List<ReportData> findSortedPublicBalance(ReportList report) {
		return reportDataDAO.findSortedPublicBalanceData(report);
	}

	public List<ReportData> findSortedPublicAsset(ReportList report) {
		return reportDataDAO.findSortedPublicAsset(report);
	}

	public List<ReportData> findSortedPublicDebt(ReportList report) {
		return reportDataDAO.findSortedPublicDebt(report);
	}

	public List<ReportData> findSortedPublicRevenue(ReportList report) {
		return reportDataDAO.findSortedPublicRevenue(report);
	}

	public List<ReportData> findSortedPublicExpend(ReportList report) {
		return reportDataDAO.findSortedPublicExpend(report);
	}

	public List<ReportData> findSortedPublicSurplus(ReportList report) {
		return reportDataDAO.findSortedPublicSurplus(report);
	}

	public List<ReportData> findSortedPublicIncome(ReportList report) {
		return reportDataDAO.findSortedPublicIncome(report);
	}

	public List<ReportData> findSortedSmallIncome(ReportList report) {
		return reportDataDAO.findSortedSmallIncome(report);
	}

	public List<CustInfo> findCustByCondition(String custType, String custName,
			String organizationId, String busiLicenseId, String custScope,
			String orgCode, String industryType, String creditLevel,String defaultStat,String exposureType, String classifyDate,String userId,String orgId) {
		List<CustInfo> custList = custInfoDao.findCustByCondition(custType, custName,organizationId, busiLicenseId, custScope, orgCode,industryType, creditLevel,defaultStat, exposureType,classifyDate);
		Iterator it = custList.iterator();
		while(it.hasNext()){
			CustInfo cust = (CustInfo) it.next();
			List<String> subOrgIdList = orgMap.get(orgId);
			if(cust.getInputUserId() == null || ( !cust.getInputUserId().equals(userId)) && !subOrgIdList.contains(cust.getInputOrgId())) it.remove();
		}
		return custList;	
		
	}
	
	public List<CustInfo> findCustByCondition(Map<String,String> custInfoCondition,String userId,String orgId){
		List<CustInfo> custList = custInfoDao.findCustByCondition(custInfoCondition);
		return custFilter(custList,userId,orgId);
		
	}
	
	public List<CustInfo> findCustByPdhCondition(Map<String,String> custInfoCondition,Map<String,String> pdhCondition,String userId,String orgId){
		List<CustInfo> custList = custInfoDao.findCustByPdhCondition(custInfoCondition,pdhCondition);
		return custFilter(custList,userId,orgId);
		
	}


	public List<CustInfo> findBiggestCustByCondition(String custType,String custScope, String exposureType,
			String orgCode, String industryType, String creditLevel,String defaultStat,String userId,String orgId) {
		List<CustInfo> custList = custInfoDao.findBiggestCustByCondition(custType,custScope,exposureType,orgCode,industryType,creditLevel,defaultStat); 
		Iterator it = custList.iterator();
		while(it.hasNext()){
			CustInfo cust = (CustInfo) it.next();
			List<String> subOrgIdList = orgMap.get(orgId);
			if(cust.getInputUserId() == null || ( !cust.getInputUserId().equals(userId)) && !subOrgIdList.contains(cust.getInputOrgId())) it.remove();
		}
		return custList;
	}

	@SuppressWarnings("unchecked")
	public List<GroupInfo> findGroupByCustId(String custId) {
		return groupInfoDAO.findByCustId(custId);
	}

	public void insertGroup(GroupInfo groupInfo) {
		groupInfoDAO.save(groupInfo);
	}

	public void deleteGroupById(String addSerialNo) {
		groupInfoDAO.delete(groupInfoDAO.findById(addSerialNo));
	}
	
	public GroupInfo findGroupById(String addSerialNo){
		return groupInfoDAO.findById(addSerialNo);
	}

	public void updateGroup(GroupInfo groupInfo) {
		groupInfoDAO.update(groupInfo);
	}
	
	@SuppressWarnings("unchecked")
	public List<MemberInfo> findMemberByCustId(String custId) {
		return memberInfoDAO.findByCustId(custId);
	}

	public void insertGroup(MemberInfo memberInfo) {
		memberInfoDAO.save(memberInfo);
	}

	public void deleteMemberById(String addSerialNo) {
		memberInfoDAO.delete(memberInfoDAO.findById(addSerialNo));
	}
	
	public MemberInfo findMemberById(String addSerialNo){
		return memberInfoDAO.findById(addSerialNo);
	}

	public void updateMember(MemberInfo memberInfo) {
		memberInfoDAO.update(memberInfo);
	}

	public void insertMember(MemberInfo memberInfo) {
		memberInfoDAO.save(memberInfo);
	}

	public List<DebtInfo> findDebtByCondition(String custName,String custType, String custScope, 
			String industryType, String exposureType, String orgCode,String debtNo, String debtName,
			String debtType, String guarantyKind, String classifyResult, String classifyDate) {
		return debtInfoDAO.findDebtByCondition(custName,custType, custScope, industryType, exposureType, orgCode, debtNo, debtName, debtType, guarantyKind, classifyResult, classifyDate);
	}
	
	public List<DebtInfo> findDebtByCondition(Map<String,String> custCondition,Map<String,String> debtCondition,String userId,String orgId){
		List<Object> list = debtInfoDAO.findDebtByCondition(custCondition, debtCondition);
		return debtFilter(list, userId, orgId);
		
	}

	@SuppressWarnings("unchecked")
	public List<IndInfo> findAllIndCustomer(String userId, String orgId) {
		
		if(userId == null || "".equals(userId) || orgId == null || "".equals(orgId)) return new ArrayList<IndInfo>();

		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");
		List<String> subOrgIdList = orgMap.get(orgId);
		List<IndInfo> resultList = indInfoDAO.findIndInfo(userId,subOrgIdList);
		//不同权限可见性不同：
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(indInfoDAO.findIndInfo(userId,selfList));
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(indInfoDAO.findIndInfo(userId,selfList));
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			List<String> selfList = new ArrayList<String>();
			selfList.add(orgId);
			resultList.addAll(indInfoDAO.findIndInfo(userId,selfList));
		}
		
		for(IndInfo cust : resultList){
			if(systemService.findUserById(cust.getInputUserId())!=null){
				String userName = systemService.findUserById(cust.getInputUserId()).getUsername();
				String orgName = systemService.findOrgById(cust.getInputOrgId()).getOrgname();
				cust.setInputUserId(userName);
				cust.setInputOrgId(orgName);
			}
		}
		
		return resultList;
		
	}

	public List<IndInfo> findIndCustomerByIdAndName(String condition,
			String keyword) {
		return indInfoDAO.findByIdAndName(condition, keyword);
	}

	@SuppressWarnings("unchecked")
	public List<AssociateAccount> findAssociateAccountByCustId(String custId) {
		return associateAccountDAO.findByCustId(custId);
	}

	public void insertAssociateAccount(AssociateAccount associateAccount) {
		associateAccountDAO.save(associateAccount);
	}

	public AssociateAccount findAssociateAccountById(String addSerialNo) {
		return associateAccountDAO.findById(addSerialNo);
	}

	public void updateAssociateAccount(AssociateAccount associateAccount) {
		associateAccountDAO.update(associateAccount);
	}

	public void deleteAssociateAccountById(String addSerialNo) {
		associateAccountDAO.delete(associateAccountDAO.findById(addSerialNo));
	}
	
	public void insertCustStockholder(CustStockholder custStockholder){
		custStockholderDAO.save(custStockholder);
	}
	
	public CustStockholder findStockholderById(String addSerialNo){
		return custStockholderDAO.findById(addSerialNo);
	}
	
	public List<CustStockholder> findStockholderByCustId(String custId){
		return custStockholderDAO.findByCustId(custId);
	}
	
	public void updateStockholder(CustStockholder custStockholder){
		custStockholderDAO.update(custStockholder);
	}
	
	public void deleteStockholderById(String addSerialNo){
		custStockholderDAO.delete(custStockholderDAO.findById(addSerialNo));
	}
	

	public List<ReportData> findFinancialIndexInCondition(String custId, String accountMonth){
		return reportDataDAO.findInCondition(custId,accountMonth,"05");
	}
	
	public Map<String, String > findReportDisplayName(String reportNo){
		List<ReportModel> list = reportModelDAO.findByReportNo(reportNo);
		Map<String,String> map = new HashMap<String,String>();
		for(ReportModel model:list){
			map.put(model.getFinanceItemNo(), model.getDisplayName());
		}
		return map;
		
	}
	
	public void updateBalance(String custId){
		List<DebtInfo> list = debtInfoDAO.findByCustId(custId);
		double balance = 0;
		for(DebtInfo debt: list){
			if(debt.getDebtBalance() != null) balance += debt.getDebtBalance();
		}
		CustInfo cust = custInfoDao.findById(custId);
		cust.setBalance(balance);
		custInfoDao.update(cust);
	}

	
	/**
	 * 过滤原则：只显示用户自己的和所管辖下属机构的客户。
	 * 同时，填充经办人与经办机构名称。
	 * @param custList
	 * @param userId
	 * @param orgId
	 * @return
	 */
	private List<CustInfo> custFilter(List<CustInfo> custList,String userId,String orgId){
		Iterator it = custList.iterator();
		List<String> subOrgIdListOriginal = orgMap.get(orgId);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");

		List<String> subOrgIdListCopy = new ArrayList<String>();
		subOrgIdListCopy.addAll(subOrgIdListOriginal);
		//不同权限可见性不同：
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			subOrgIdListCopy.add(orgId);
		}
		
		
		while(it.hasNext()){
			CustInfo cust = (CustInfo) it.next();
			if(cust.getInputUserId() == null || ( !cust.getInputUserId().equals(userId)) && !subOrgIdListCopy.contains(cust.getInputOrgId())) it.remove();
			else{
				String userName = "";
				String orgName = "";
				UserInfo user = systemService.findUserById(cust.getInputUserId());
				OrgInfo org = systemService.findOrgById(cust.getInputOrgId());
				if(user != null)userName = user.getUsername();
				if(org != null) orgName = org.getOrgname();
				cust.setInputUserName(userName);
				cust.setInputOrgName(orgName);
			}
		}
		return custList;
	}
	
	/**
	 * 过滤原则：只显示用户自己的和所管辖下属机构的客户的债项。
	 * 同时，填充经办人与经办机构名称。此处默认债项的经办人、经办机构为债项所属客户的经办人、经办机构
	 * @param debtList
	 * @param userId
	 * @param orgId
	 * @return
	 */
	private List<DebtInfo> debtFilter(List<Object> list,String userId,String orgId){
		List<DebtInfo> resultList = new ArrayList<DebtInfo>();
		
		List<String> subOrgIdListOriginal = orgMap.get(orgId);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");

		List<String> subOrgIdListCopy = new ArrayList<String>();
		subOrgIdListCopy.addAll(subOrgIdListOriginal);
		//不同权限可见性不同：
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			subOrgIdListCopy.add(orgId);
		}
		
		for(Object obj :list){
			Object[] items = (Object[]) obj;
			CustInfo cust = (CustInfo) items[1];
			if(cust.getInputUserId() == null || ( !cust.getInputUserId().equals(userId)) && !subOrgIdListCopy.contains(cust.getInputOrgId()));
			else{
				String userName = "";
				String orgName = "";
				UserInfo user = systemService.findUserById(cust.getInputUserId());
				OrgInfo org = systemService.findOrgById(cust.getInputOrgId());
				if(user != null)userName = user.getUsername();
				if(org != null) orgName = org.getOrgname();
				
				DebtInfo debt = (DebtInfo) items[0];
				debt.setInputUserId(userName);
				debt.setInputOrgId(orgName);
				resultList.add(debt);
			}
		}
		return resultList;
	}

	public String getCustNameByCustNo(String debtCustId) {
		return custInfoDao.findByCustNo(debtCustId);
	}

	public String getCustIdByCustNo(String debtCustId) {
		return custInfoDao.findCustIdByCustNo(debtCustId);
	}

	public List<IndInfo> findIndCustByCondition(Map<String, String> condition,
			String userId, String orgId) {
		List<IndInfo> custList = indInfoDAO.findCustByCondition(condition);
		return indCustFilter(custList,userId,orgId);
	}

	private List<IndInfo> indCustFilter(List<IndInfo> custList, String userId,
			String orgId) {
		Iterator it = custList.iterator();
		List<String> subOrgIdListOriginal = orgMap.get(orgId);
		List<RoleInfo> roleList = systemService.findRoleByUserId(userId);
		String accessURL = RoleRightInit.getInstance().getRightMap().get(roleList.get(0).getRoleId()).get("accessURL");

		List<String> subOrgIdListCopy = new ArrayList<String>();
		subOrgIdListCopy.addAll(subOrgIdListOriginal);
		//不同权限可见性不同：
		//权限--评级发起
		if(accessURL.contains("CustomerRating_FirstPD")){
		}
		//权限--评级复评
		else if(accessURL.contains("CustomerRating_FirstVerifyPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级审核
		else if(accessURL.contains("CustomerRating_SecondPD")){
			subOrgIdListCopy.add(orgId);
		}
		//权限--评级认定
		else if(accessURL.contains("CustomerRating_ConfirmPD")){
			subOrgIdListCopy.add(orgId);
		}
		
		while(it.hasNext()){
			IndInfo cust = (IndInfo) it.next();
			if(cust.getInputUserId() == null || ( !cust.getInputUserId().equals(userId)) && !subOrgIdListCopy.contains(cust.getInputOrgId())) it.remove();
			else{
				String userName = "";
				String orgName = "";
				UserInfo user = systemService.findUserById(cust.getInputUserId());
				OrgInfo org = systemService.findOrgById(cust.getInputOrgId());
				if(user != null)userName = user.getUsername();
				if(org != null) orgName = org.getOrgname();
				cust.setInputUserName(userName);
				cust.setInputOrgName(orgName);
			}
		}
		return custList;
	}
	
	public void sortByPDState(List<Map<String,Object>> list){
		int length = list.size();
		if(length == 0 || length == 1) return ;
		int top = 0;
		int bottom = length - 1;
		int point = top;
		String NOT_RATTING = DataDictionary.getInstance().getNameByCodeAndId("PhaseStat", PdH.NOT_RATTING);
		String CONFIRM_FINISH = DataDictionary.getInstance().getNameByCodeAndId("PhaseStat", PdH.CONFIRM_FINISH);
		while(point <= bottom){
			String phaseStat = ((PdH)(list.get(point).get("custPD"))).getPhaseStat();
			if(phaseStat.equals(NOT_RATTING)){
				if(point != top){
					Map<String,Object> temp = list.get(top);
					list.set(top, list.get(point));
					list.set(point,temp);
				}
				top++;
				point++;
			}
			else if(phaseStat.endsWith(CONFIRM_FINISH)){
				if(point == bottom) break;
				if(((PdH)(list.get(bottom).get("custPD"))).getPhaseStat().equals(CONFIRM_FINISH)){
					bottom--;
					continue;
				}
				Map<String,Object> temp = list.get(bottom);
				list.set(bottom,list.get(point));
				list.set(point,temp);
				bottom--;
			}
			else point++;
		}
	}
}
